package org.beynet.docs.format;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import javax.xml.transform.stream.StreamResult;

import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;

import org.apache.log4j.Logger;
import org.beynet.docs.exceptions.GDocsServerError;
import org.beynet.docs.helpers.XmlHelper;
import org.beynet.docs.http.GDocsHTTPConstants;
import org.beynet.docs.session.SessionImpl;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

/**
 * represent a feed representing a collection of google docs elements.
 * @author beynet
 *
 */
public class DocumentListFeed {
    public DocumentListFeed(Document feed) throws GDocsServerError {
        this.doc = feed ;
        retrieveLinks();
        retrieveEntries();
    }
    public DocumentListFeed(){
        this.doc = null ;
        this.links = new ArrayList<Link>();
        this.entries = new ArrayList<DocumentListEntry>();
    }
    
    public Link getResumableCreateMediaLink(){
        return(getLink(GDocsHTTPConstants.RESUMABLE_CREATE_REL_LINK));
    }
    
    public Link getLink(String rel) {
        for (Link l : getLinks()) {
            if (rel.equals(l.getRel())) {
                return(l);
            }
        }
        return(null);
    }
    
    public Link getNextLink() {
        for (Link l : getLinks()) {
            if (GDocsHTTPConstants.NEXT_REL.equals(l.getRel())) {
                return(l);
            }
        }
        return(null);
    }
    
    public List<Link> getParentLinks() {
        List<Link> result = new ArrayList<Link>();
        for (Link l : getLinks()) {
            if (GDocsHTTPConstants.PARENT_REL.equals(l.getRel())) {
                result.add(l);
            }
        }
        return(result);
    }
    
    
    
    /**
     * retrieve all the links found in the document list feed
     */
    private void retrieveLinks() {
        links = new ArrayList<Link>();
        NodeList linksNodes = null ;
        try {
            linksNodes = (NodeList) XmlHelper.getXPathInterpretorForGDocsAtom().evaluate("/atom:feed/atom:link", doc, XPathConstants.NODESET);
        } catch (XPathExpressionException e) {
            throw new RuntimeException("Unexpected exception when processing xpath",e);
        }
        Link.makeFromNodeList(links, linksNodes);
    }
    
    private void retrieveEntries() throws GDocsServerError {
        entries = new ArrayList<DocumentListEntry>();
        NodeList entriesNodes = null ;
        try {
            entriesNodes = (NodeList) XmlHelper.getXPathInterpretorForGDocsAtom().evaluate("/atom:feed/atom:entry", doc, XPathConstants.NODESET);
        } catch (XPathExpressionException e) {
            throw new RuntimeException("Unexpected exception when processing xpath",e);
        }
        DocumentListEntry.makeFromNodeList(entriesNodes, entries);
    }
    
    public List<Link> getLinks() {
        return(links);
    }
    
    public List<DocumentListEntry> getEntries() {
        return(entries);
    }
    
    public void printDoc() {
        try {
            javax.xml.transform.TransformerFactory.newInstance().newTransformer().transform(new javax.xml.transform.dom.DOMSource(doc), new StreamResult(System.err));
        } catch (Exception ex) {
            java.util.logging.Logger.getLogger(SessionImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    private List<Link>              links   ;
    private List<DocumentListEntry> entries ;
    private Document                doc     ;
    
    @SuppressWarnings("unused")
    private final static Logger logger  = Logger.getLogger(DocumentListFeed.class);
}
